home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / NumTut / view.py < prev   
Text File  |  2006-01-20  |  4KB  |  125 lines

  1. """
  2. Displaying image files in a separate thread on Tk+thread, w/ xv in
  3. forked & execv'ed processes otherwise.
  4.  
  5. view(array):  will spawn a displaying program for arrays which are
  6.               either NxM or NxMx3.  does the 'min/max' and conversion
  7.               to char.
  8.  
  9. array2ppm(array): given an NxM or NxMx3 array, returns a ppm string
  10.                   which is a valid thing to put in a PPM file.  (or
  11.                   PGM file if NxM file).
  12.  
  13. TODO:
  14.   - automatic scaling for small images
  15.   - accept rank-1 arrays
  16.  
  17. NOTE: This is a modified version which removes all threading and PIL
  18. support. It should work on any system with Tkinter alone.
  19.  
  20. """
  21.  
  22. DEFAULT_HEIGHT = 255
  23. MINSIZE = 150
  24.  
  25. import os
  26. import Tkinter
  27. from Numeric import *
  28. import tempfile, time
  29.  
  30.  
  31. def save_ppm(ppm, fname=None):
  32.     if fname == None:
  33.         fname = tempfile.mktemp('.ppm')
  34.     f = open(fname, 'wb')
  35.     f.write(ppm)
  36.     f.close()
  37.     return fname
  38.  
  39.  
  40. def array2ppm(image):
  41.     # scaling
  42.     if len(image.shape) == 2:
  43.         # B&W:
  44.         image = transpose(image)
  45.         return "P5\n#PPM version of array\n%d %d\n255\n%s" % \
  46.                (image.shape[1], image.shape[0], ravel(image).tostring())
  47.     else:
  48.         # color
  49.         image = transpose(image, (1, 0, 2))
  50.         return "P6\n%d %d\n255\n%s" % \
  51.                (image.shape[1], image.shape[0], ravel(image).tostring())
  52.  
  53. def preprocess(image, (scalex,scaley)):
  54.     assert len(image.shape) in (1, 2) or \
  55.            len(image.shape) == 3 and image.shape[2] == 3, \
  56.            "image not correct format"
  57.     themin = float(minimum.reduce(ravel(image)))
  58.     themax = float(maximum.reduce(ravel(image)))
  59.     if len(image.shape) == 1:
  60.         len_x = image.shape[0]
  61.         ys = ((image - themin)/(themax-themin)*(DEFAULT_HEIGHT-1)).astype('b')
  62.         image = (zeros((DEFAULT_HEIGHT, len_x))+255).astype('b')
  63.         for x in range(len_x):
  64.             image[DEFAULT_HEIGHT-1-ys[x],len_x-x-1] = 0
  65.         image = transpose(image)
  66.     elif image.typecode() != 'b':
  67.         image = (image - themin) / (themax-themin) * 255
  68.         image = image.astype('b')
  69.  
  70.     len_x, len_y = image.shape[:2]
  71.     if scalex is None:
  72.         if len_x < MINSIZE:
  73.             scalex = int(float(MINSIZE) / len_x) + 1
  74.         else:
  75.             scalex = 1
  76.     if scaley is None:
  77.         if len_y < MINSIZE:
  78.             scaley = int(float(MINSIZE) / len_y) + 1
  79.         else:
  80.             scaley = 1
  81.     return image, (scalex, scaley)
  82.  
  83.  
  84. class PPMImage(Tkinter.Label):
  85.     def __init__(self, master, ppm, (scalex, scaley)):
  86.         self.image = Tkinter.PhotoImage(file=save_ppm(ppm))
  87.         w, h = self.image.width(), self.image.height()
  88.         self.image = self.image.zoom(scalex, scaley)
  89.         self.image.configure(width=w*scalex, height=h*scaley)
  90.         Tkinter.Label.__init__(self, master, image=self.image,
  91.                                bg="black", bd=0)
  92.  
  93.         self.pack()
  94.  
  95. # Start the Tk process from which all subsequent windows will be opened.
  96. def tk_root():
  97.     if Tkinter._default_root is None:
  98.         root = Tkinter.Tk()
  99.         Tkinter._default_root.withdraw()
  100.     else:
  101.         root = Tkinter._default_root
  102.     return root
  103.  
  104. _root = tk_root()
  105.  
  106. def view(image, scale=None):
  107.     """Display an image, optionally rescaling it.
  108.  
  109.     scale can be either an integer or a tuple of 2 integers (for separate x/y
  110.     rescaling.  """
  111.  
  112.     if scale is None:
  113.         scale=(None,None)
  114.     else:
  115.         try:
  116.             len(scale)
  117.         except TypeError:
  118.             scale = (scale,scale)
  119.  
  120.     image, scales = preprocess(image, scale)
  121.     tl = Tkinter.Toplevel()
  122.     u = PPMImage(tl, array2ppm(image), scales)
  123.     u.pack(fill='both', expand=1)
  124.     u.tkraise()
  125.